package com.example.easyexcel.controller;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.builder.ExcelReaderBuilder;
import com.alibaba.fastjson.JSON;
import com.example.easyexcel.dao.LitemallRegionDao;
import com.example.easyexcel.utils.ExcelDemoListener;
import io.swagger.annotations.ApiOperation;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

//import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.poi.ss.usermodel.Sheet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import com.example.easyexcel.entity.LitemallRegion;
import com.example.easyexcel.service.LitemallRegionService;
import com.example.easyexcel.utils.R;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;


/**
 * 行政区域表
 *
 * @author VSHDI
 * @email vshd1@163.com
 * @date 2020-08-05 17:04:41
 */
@RestController
@RequestMapping("easyexcel/litemallregion")
public class LitemallRegionController {

    @Autowired
    private LitemallRegionService litemallRegionService;
    @Autowired
    private LitemallRegionDao litemallRegionDao;

    /**
     * 普通的写
     * 从数据库查出数据，写入Excel
     * 可以先处理数据再写入
     * @param path
     * @return
     */
    @GetMapping("/write")
    @ApiOperation(value = "写入Excel", notes = "EasyExcel实现数据库写入Excel")
    public R write(@RequestParam(defaultValue = "E:\\V\\EasyExcelDemo2\\") String path) {
        String fileName = pathChange(path)+"EasyExcel.xlsx";
//        String fileName = "E:\\V\\EasyExcelDemo2\\"+"EasyExcel.xlsx";
        List<LitemallRegion> list = litemallRegionDao.selectList(null);
        EasyExcel.write(fileName, LitemallRegion.class).sheet("模板").doWrite(list);
        return R.ok().put("msg", "从数据库拿出数据写入Excel成功");
    }
    // 方法 —— 如果传入地址末尾不是'\'结尾的，添加上
    private String pathChange(String path) {
        if (path.charAt(path.length()-1)!='\\')
            path+='\\';
        return path;
    }

    /**
     * 从Excel中拿出数据写入数据库
     * 可以在监听器中对数据进行处理
     * @param path
     * @return
     */
    @PostMapping("/read")
    @ApiOperation(value = "写入Excel", notes = "EasyExcel实现Excel写入数据库")
    public R read(@RequestParam(defaultValue = "E:\\V\\EasyExcelDemo2\\") String path) {
        // 写法1：
        String fileName =path+"EasyExcel.xlsx";
        // 这里 需要指定读用哪个class去读，然后读取第一个sheet 文件流会自动关闭
        EasyExcel.read(fileName, LitemallRegion.class, new ExcelDemoListener()).sheet().doRead();
        return R.ok().put("msg","从Excel中拿出数据存入数据库成功");
    }


    /**
     * web上传——从Excel中拿出数据写入数据库
     * 文件上传
     * <p>
     * 1. 创建excel对应的实体对象 参照{ UploadData}
     * <p>
     * 2. 由于默认一行行的读取excel，所以需要创建excel一行一行的回调监听器，参照{ UploadDataListener}
     * <p>
     * 3. 直接读即可
     */
    @PostMapping("upload")
    @ResponseBody
    public String upload(MultipartFile file) throws IOException {
        EasyExcel.read(file.getInputStream(), LitemallRegion.class, new ExcelDemoListener(litemallRegionDao)).sheet().doRead();
        return "success";
    }

    /**
     * 访问路径——下载Excel文件（从数据库写入）
     * 文件下载（失败了会返回一个有部分数据的Excel）
     * <p>
     * 1. 创建excel对应的实体对象 参照{ DownloadData}
     * <p>
     * 2. 设置返回的 参数
     * <p>
     * 3. 直接写，这里注意，finish的时候会自动关闭OutputStream,当然你外面再关闭流问题不大
     */
    @GetMapping("download")
    public void download(HttpServletResponse response) throws IOException {
        // 从数据库中拿出数据
        List<LitemallRegion> list = litemallRegionDao.selectList(null);

        // 这里注意 有同学反应使用swagger 会导致各种问题，请直接用浏览器或者用postman
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("测试", "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
        EasyExcel.write(response.getOutputStream(), LitemallRegion.class).sheet("模板").doWrite(list);
    }

    /**
     * 访问路径——下载Excel文件（从数据库写入）
     * 文件下载并且失败的时候返回json（默认失败了会返回一个有部分数据的Excel）
     *
     * @since 2.1.1
     */
    @GetMapping("downloadFailedUsingJson")
    public void downloadFailedUsingJson(HttpServletResponse response) throws IOException {
        // 这里注意 有同学反应使用swagger 会导致各种问题，请直接用浏览器或者用postman
        try {
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
            String fileName = URLEncoder.encode("文件名字", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
            // 这里需要设置不关闭流
            EasyExcel.write(response.getOutputStream(), LitemallRegion.class).autoCloseStream(Boolean.FALSE).sheet("模板")
                    .doWrite(litemallRegionDao.selectList(null));
        } catch (Exception e) {
            // 重置response
            response.reset();
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            Map<String, String> map = new HashMap<String, String>();
            map.put("status", "failure");
            map.put("message", "下载文件失败" + e.getMessage());
            response.getWriter().println(JSON.toJSONString(map));
        }
    }
}
